package com.koron.housing.excel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;

/**
 * 根据某一列的数据去合并某几列
 * 根据某列function 去合并那些列needMergeColumn
 * 比如根据code字段合并相同的设备分类数据，技术参数不合并
 * @author jzp
 * @since 2022/5/17
 */
public class SameRowMargeStrategy<T> extends AbstractMergeStrategy {

    // <startRowIndex, endRowIndex>
    private final Map<Integer, Integer> cellMap = new HashMap<>();
    private Set<Integer> needMergeColumn = new HashSet<>();
    private final Set<Integer> needClearRow = new HashSet<>();

    public SameRowMargeStrategy(List<T> list, Set<Integer> needMergeColumn, Function<T, Object> function) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        int preIndex = 0;
        for (int i = 1; i < list.size(); i++) {
            if (Objects.equals(function.apply(list.get(i)), function.apply(list.get(preIndex)))) {
                cellMap.put(preIndex, i);
                needClearRow.add(i);
            } else {
                preIndex = i;
            }
        }
        this.needMergeColumn = needMergeColumn;
    }

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (needMergeColumn.contains(cell.getColumnIndex()) && cellMap.get(relativeRowIndex) != null){
            int headHeight = cell.getRowIndex() - relativeRowIndex; // 表头高度
            CellRangeAddress cellRangeAddress = new CellRangeAddress(cell.getRowIndex(), cellMap.get(relativeRowIndex) + headHeight, cell.getColumnIndex(), cell.getColumnIndex());
            sheet.addMergedRegionUnsafe(cellRangeAddress);
            RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet);
        }
        // 合并单元格后，当前单元格数据清空
        if (needMergeColumn.contains(cell.getColumnIndex()) && needClearRow.contains(relativeRowIndex)) {
            cell.setCellValue("");
        }
    }

}
